fn main() {
    let example = |x| x;

    let s = example(String::from("hello"));
    // 前面已经限定了example这个闭包的返回值类型了，后面无法改变成其他的类型
    // let n = example(5);

    let y = 5;
    let z = 10;
    let c = vec![5];

    // Fn闭包  通过引用捕获变量
    let add = |a| a + y;

    // FnMut 闭包：通过可变引用捕获变量
    let mut multiply = |a| {
        z * y * a
    };

    // FnOnce 闭包：通过值捕获变量
    let divide = move |a| {
        a / c[0]
    };

    println!("{:?}",c);

    let result1 = add(3);
    let result2 = multiply(2);
    let result3 = divide(10);

    println!("The results are: {}, {}, {}", result1, result2, result3);

    let print_hello = || print!("Hello world!");

    print_name(print_hello);

    let closure = create_closure();
    closure();

    let x = vec![1,2,3];

    let equal_to_x = move |z: Vec<i32>| z==x;

    print!("{:?}",x);
}

fn print_name<F>(f: F)
    where F: FnOnce(),
{
    f()
}

fn create_closure() -> impl Fn() {
    let x = 5;
    move || println!("The value of x is {}", x)
}


